package dk.pun.dums.shared.character;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.jdo.annotations.EmbeddedOnly;
import javax.jdo.annotations.PersistenceCapable;

@SuppressWarnings("serial")
@PersistenceCapable @EmbeddedOnly
public class CharacterAbilities implements Serializable {

	private Ability clanAbility;
	private Set<Ability> characterAbilities;
	
	public CharacterAbilities() {
		this.characterAbilities = new HashSet<Ability>();
	}

	public Ability getClanAbility() {
		return this.clanAbility;
	}
	
	public void setClanAbility(final Clan clan) {
		if (clan == null) {
			throw new IllegalArgumentException("Clan must not be null.");
		} else {
			this.clanAbility = clan.getAbility();
			if (this.clanAbility != null) {
				this.characterAbilities.remove(this.clanAbility);
				if (this.characterAbilities.size() > 2 && !this.characterAbilities.isEmpty()) {
					final Iterator<Ability> iterator = this.characterAbilities.iterator();
					iterator.next();
					iterator.remove();
				}
			}
		}
	}
	
	public Set<Ability> getCharacterAbilities() {
		return this.characterAbilities;
	}
	
	public boolean addTrainedAbility(final Ability ability) {
		if (ability == null) {
			throw new IllegalArgumentException("Ability must not be null.");
		}
		boolean result;
		if (this.isAllTrained()) {
			result = false;
		} else {
			result = this.characterAbilities.add(ability);
		}
		return result;
	}
	
	public boolean removeTrainedAbility(final Ability ability) {
		if (ability == null) {
			throw new IllegalArgumentException("Ability must not be null.");
		}
		return this.characterAbilities.remove(ability);
	}
	
	public boolean isTrainedAbility(final Ability ability) {
		boolean result;
		if (ability != null && (this.isClanAbility(ability) || this.characterAbilities.contains(ability))) {
			result = true;
		} else {
			result = false;
		}
		return result;
	}
	
	public boolean isClanAbility(final Ability ability) {
		return (ability != null && ability.equals(this.clanAbility));
	}
	
	public boolean isAllTrained() {
		int size = this.characterAbilities.size();
		if (this.clanAbility != null) {
			size++;
		}
		return (size == 3);
	}
}
